#include "gtest/gtest.h"
#include "viml/compiler.h"
#include "viml/vm.h"

using namespace viml;

class FibonacciTest : public ::testing::Test {
protected:
    Compiler compiler;
    VM vm;
    
    Value execute_source(const std::string& source) {
        auto bytecode = compiler.compile(source, "<test>");
        return vm.execute(bytecode);
    }
};

// 测试斐波那契函数
TEST_F(FibonacciTest, FibonacciFunction) {
    std::string source = R"(
        function Fibonacci(n)
            if n <= 1
                return n
            endif
            
            let a = 0
            let b = 1
            let i = 2
            
            while i <= n
                let temp = a + b
                let a = b
                let b = temp
                let i = i + 1
            endwhile
            
            return b
        endfunction
        
        let result0 = Fibonacci(0)
        let result1 = Fibonacci(1)
        let result5 = Fibonacci(5)
        let result10 = Fibonacci(10)
    )";
    
    Value result = execute_source(source);
    
    EXPECT_TRUE(vm.has_global("result0"));
    Value result0_val = vm.get_global("result0");
    EXPECT_TRUE(result0_val.is_number());
    EXPECT_EQ(result0_val.as_number(), 0.0);
    
    EXPECT_TRUE(vm.has_global("result1"));
    Value result1_val = vm.get_global("result1");
    EXPECT_TRUE(result1_val.is_number());
    EXPECT_EQ(result1_val.as_number(), 1.0);
    
    EXPECT_TRUE(vm.has_global("result5"));
    Value result5_val = vm.get_global("result5");
    EXPECT_TRUE(result5_val.is_number());
    EXPECT_EQ(result5_val.as_number(), 5.0);
    
    EXPECT_TRUE(vm.has_global("result10"));
    Value result10_val = vm.get_global("result10");
    EXPECT_TRUE(result10_val.is_number());
    EXPECT_EQ(result10_val.as_number(), 55.0);
}